tb_TrafficLightFSM.sv

Modified

2025-11-11

Source: HW6/tb_TrafficLightFSM.sv.sv (modified 2025-11-09 23:49)

// tb_traffic_light_fsm.sv
`timescale 1ns/1ps

module tb_TrafficLightFSM;

    // 100 MHz 时钟(10 ns 周期)
    logic clk = 0;
    always #5 clk = ~clk;

    logic rst_n;

    // DUT 输出
    logic LA_R, LA_Y, LA_G;
    logic LB_R, LB_Y, LB_G;
    logic [2:0] LA, LB;

    // 为了快速演示:把“1秒”缩到 10 个时钟周期(=100 ns)
    localparam int CLK_HZ_TB  = 100_000_000;         // 10 ns 周期
    localparam int TICK_HZ_TB = CLK_HZ_TB / 10;      // 10 周期一个“秒拍” => 100 ns/秒
    // 于是 5 “秒” = 500 ns,在波形中非常清晰

    TrafficLightFSM #(
        .CLK_HZ   (CLK_HZ_TB),
        .TICK_HZ  (TICK_HZ_TB),
        .T_A_GREEN(4),
        .T_A_YEL  (2),
        .T_B_GREEN(4),
        .T_B_YEL  (2),
        .T_ALL_RED(5)   // 关键:5 秒双红
    ) dut (
        .clk  (clk),
        .rst_n(rst_n),
        .LA_R(LA_R), .LA_Y(LA_Y), .LA_G(LA_G),
        .LB_R(LB_R), .LB_Y(LB_Y), .LB_G(LB_G),
        .LA  (LA),
        .LB  (LB)
    );

    // 复位 & 运行
    initial begin
        rst_n = 0;
        repeat (5) @(posedge clk);
        rst_n = 1;

        // 估算一个完整循环时长:
        // A_G(4) + A_Y(2) + ALL_RED(5) + B_G(4) + B_Y(2) + ALL_RED(5) = 22 “秒”
        // 22 * 100 ns = 2.2 us。一口气跑 60 us 肯定覆盖很多圈
        #60000; // 60 us
        $finish;
    end

    // 便于控制台阅读的彩色文本(把 RGB 映射成字符串)
    function string color3(input logic r, input logic y, input logic g);
        if (r) return "RED";
        else if (y) return "YEL";
        else if (g) return "GRN";
        else return "---";
    endfunction

    // 打印状态与灯色
    initial begin
        $display("time (ns)\tA\tB\tstate");
        forever begin
            @(posedge clk);
            // 利用 SV 2012 的枚举 name() 方法打印符号名
            $display("%0t\t%s\t%s\t%s",
                $time, color3(LA_R,LA_Y,LA_G), color3(LB_R,LB_Y,LB_G), dut.state.name()
            );
        end
    end

endmodule